#pragma once

#include "ResourceFiles\IResourceFile.h"

#include "ResourceLoaders\IResourceLoader.h"

#include "ResourceHandle.h"

typedef std::list<shared_ptr<ResourceHandle> > ResourceHandleList;					// lru list
typedef std::map<std::string, shared_ptr<ResourceHandle> > ResourceHandleMap;		// maps indentifiers to resource data
typedef std::list<shared_ptr<IResourceLoader> > ResourceLoaders;

class ResourceCache
{
	friend class ResourceHandle;

	ResourceHandleList _lru;							// lru list
	ResourceHandleMap _resources;
	ResourceLoaders _resourceLoaders;

	IResourceFile* _pResourceFile;

	unsigned int _cacheSize;			// total memory size
	unsigned int _allocated;			// total memory allocated

	protected:

		bool MakeRoom(unsigned int size);

		char* Allocate(unsigned int size);

		void Free(shared_ptr<ResourceHandle> gonner);

		shared_ptr<ResourceHandle> Load(Resource *r);

		shared_ptr<ResourceHandle> Find(Resource *r);

		void Update(shared_ptr<ResourceHandle> handle);

		void FreeOneResource();

		void MemoryHasBeenFreed(unsigned int size);

	public:
		
		ResourceCache(const unsigned int sizeInMb, IResourceFile *file);

		virtual ~ResourceCache();

		bool Init(); 
	
		void RegisterLoader(shared_ptr<IResourceLoader> loader);

		shared_ptr<ResourceHandle> GetHandle(Resource *r);

		int Preload(
			const std::string pattern, 
			void (*progressCallback)(int, bool &));

		std::vector<std::string> Match(const std::string pattern);

		void Flush();
};